package controlador;

import java.io.ObjectOutputStream;
import java.net.Socket;
import modelo.servicios.InformacionBasica;
import org.apache.log4j.Logger;

/**
 * Clase que se encarga de comunicar el tanque actual con otro tanque
 * @author Eduardo
 */
public class EnvioMensajes extends Thread {

    private float cantidadAenviar;
    private static Logger logger = Logger.getLogger(EnvioMensajes.class);

    /**
     * Constructor vacío de la clase
     */
    public EnvioMensajes() {}

    /**
     * Constructor de la clase. Inicia la ejecución del hilo
     * @param cantidadAenviar Cantidad de petróleo que el tanque actual enviará al tanque adyacente
     */
    public EnvioMensajes(float cantidadAenviar) {
        this.cantidadAenviar = cantidadAenviar;
        start();      
    }

    @Override
    public void run() {
        InformacionBasica ib = (new Informacion()).obtenerInformacionBasica();

        try {
            int idTanqueAdyacente = 0;

            if (ib.getIdTanque() == 1)
                idTanqueAdyacente = 2;

            if (ib.getIdTanque() == 2)
                idTanqueAdyacente = 3;

            if (ib.getIdTanque() == 3)
                idTanqueAdyacente = 1;

            /**
             * Abriendo vía de envío del documento XML al tanque adyacente
             */
            Socket socket = new Socket(ib.getIpSSOTR(), ib.getPuertoSSOTR());
            ObjectOutputStream oOutput = new ObjectOutputStream(socket.getOutputStream());

            String documentoXML = "<tanque>\n\t<id>" + idTanqueAdyacente + "</id>\n\t<lts>" +
                    getCantidadAenviar() +
                    "</lts>\n</tanque>";
            logger.info("Transfiriendo " + getCantidadAenviar() + " litros de petroleo al tanque "
                    + idTanqueAdyacente);
            System.out.println("Transfiriendo " + getCantidadAenviar() + " litros de petróleo al "
                    + "tanque " + idTanqueAdyacente);

            oOutput.writeObject(documentoXML);

            /**
             * Cerrando vía de envío del documento XML al tanque
             */
            oOutput.close();
            socket.close();            
        } catch (Exception e) {
            logger.error("Problemas al enviar el mensaje al otro equipo por el ip " +
                    ib.getIpSSOTR() + " y el puerto " + ib.getPuertoSSOTR());
            System.out.println("Problemas al enviar el mensaje al otro equipo por el ip " +
                    ib.getIpSSOTR() + " y el puerto " + ib.getPuertoSSOTR());
        }
    }

    /**
     * Envía la orden de impresión de colapso del sistema a los nodos no coordinadores. Método
     * utilizado exclusivamente por el nodo coordinador
     * @param mensajeColapso Mensaje a ser enviado a cada uno de los nodos no coordinadores
     */
    public void enviarMensajeColapso(String mensajeColapso) {
        InformacionBasica ib = (new Informacion()).obtenerInformacionBasica();

        try {
            /**
             * Abriendo vía de envío del mensaje de colapso al primer tanque no coordinador
             */
            Socket socket = new Socket(ib.getIpRSDR1(), ib.getPuertoRSDR1());
            ObjectOutputStream oOutput = new ObjectOutputStream(socket.getOutputStream());

            if (!mensajeColapso.equals("false")) {
                logger.info("Enviando mensaje de colapso del sistema al primer tanque no "
                        + "coordinador de identificador " + ib.getIdTanque1() + "\n'" +
                        mensajeColapso + "'");
                System.out.println("Enviando mensaje de colapso del sistema al primer tanque no "
                        + "coordinador de identificador " + ib.getIdTanque1() + "\n'" +
                        mensajeColapso + "'");
            }
            
            oOutput.writeObject(mensajeColapso);

            /**
             * Cerrando vía de envío del mensaje de colapso al primer tanque no coordinador
             */
            oOutput.flush();
            oOutput.close();
            socket.close();

            /**
             * Abriendo vía de envío del mensaje de colapso al segundo tanque no coordinador
             */
            socket = new Socket(ib.getIpRSDR2(), ib.getPuertoRSDR2());
            oOutput = new ObjectOutputStream(socket.getOutputStream());

            if (!mensajeColapso.equals("false")) {
                logger.info("Enviando mensaje de colapso del sistema al segundo tanque no "
                        + "coordinador de identificador " + ib.getIdTanque2() + "\n'" +
                        mensajeColapso + "'");
                System.out.println("Enviando mensaje de colapso del sistema al segundo tanque no "
                        + "coordinador de identificador " + ib.getIdTanque2() + "\n'" + 
                        mensajeColapso + "'");
            }
            
            oOutput.writeObject(mensajeColapso);

            /**
             * Cerrando vía de envío del mensaje de colapso al segundo tanque no coordinador
             */
            oOutput.flush();
            oOutput.close();
            socket.close();            
        } catch (Exception e) {
            logger.error("Problemas al enviar el mensaje al otro equipo");
            System.out.println("Problemas al enviar el mensaje al otro equipo");
        }
    }

    /**
     * Envía mensaje de colapso al nodo coordinador
     * @param mensajeColapso Mensaje a ser enviado al nodo coordinador
     */
    public void enviarMensajeColapsoCoordinador(String mensajeColapso) {
        InformacionBasica ib = (new Informacion()).obtenerInformacionBasica();

        try {
            /**
             * Abriendo vía de envío del mensaje de colapso al tanque coordinador
             */
            Socket socket = new Socket(ib.getIpC(), ib.getPuertoC());
            ObjectOutputStream oOutput = new ObjectOutputStream(socket.getOutputStream());

            logger.info("Enviando mensaje de colapso del sistema al tanque coordinador: '"
                    + mensajeColapso + "'");
            System.out.println("Enviando mensaje de colapso del sistema al tanque coordinador:\n'"
                    + mensajeColapso + "'");
            oOutput.writeObject(mensajeColapso);

            /**
             * Cerrando vía de envío del mensaje de colapso al primer tanque no coordinador
             */
            oOutput.flush();
            oOutput.close();
            socket.close();            
        } catch (Exception e) {
            logger.error("Problemas al enviar el mensaje al nodo coordinador");
            System.out.println("Problemas al enviar el mensaje al nodo coordinador");
        }
    }


    /**
     * @return the cantidadAenviar Devuelve la cantidad de litros a enviar al puerto adyacente
     */
    public float getCantidadAenviar() {
        return cantidadAenviar;
    }

    /**
     * @param cantidadAenviar the cantidadAenviar to set Asigna un valor a la cantidad de litros a
     * enviar al puerto adyacente
     */
    public void setCantidadAenviar(float cantidadAenviar) {
        this.cantidadAenviar = cantidadAenviar;
    }
}